/*
Copyright 2009 Lawren Quigley-Jones

   board-assistant.js is part of Preopoly.

   Preopoly is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   Preopoly is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Preopoly.  If not, see <http://www.gnu.org/licenses/>.

   Contact Lawren Quigley-Jones with questions or bugs:
   lawrenqj@gmail.com
*/

function BoardAssistant() {
}

BoardAssistant.prototype.setup = function() {
  this.pause = false;
		// set the menu bar
  var myMenuAttr = {omitDefaultItems: true};
  this.myMenuModel = {
	visible: true,
	items: [
	    { label: "Preferences", command: 'do-prefs' },
            { label: "Assets", command: 'do-assets', disabled: true },
	    { label: "Help", command: 'do-help' }
	]
  };
  this.controller.setupWidget(Mojo.Menu.appMenu, myMenuAttr, this.myMenuModel );

  if ( prefs.bankMode == 'true' ) {
    this.myMenuModel.items[1]['disabled'] = false;
    this.controller.modelChanged(this.myMenuModel, this);
    this.controller.get('PropertiesButtonID').style.left = "214px";
    this.controller.get('PropertiesButtonID').style.visibility = "visible";
  }

		// arrays of shuffle card numbers
  this.chanceShuffle = shuffleCards(chanceCards.length);
  this.communitychestShuffle = shuffleCards(communitychestCards.length);

  this.createPropertyDivs();

  this.controller.get('PlayerID').update(playerArray[curPlayer].playerName);
  this.printMoney();
  //this.printPlayer(curPlayer, playerArray[curPlayer].position);
  this.printCard(playerArray[curPlayer].position);

		// the icon for 0 is going to be part of the "movePlayer", but we need to do it for the rest.
  for ( var i=0; i<prefs.numPlayers; i++ ) {
    if ( playerArray[playerList[i]].bankrupt ) continue;
    this.printPlayer(playerList[i], playerArray[playerList[i]].position);
  }

  this.updateFreeParking(0);

  if ( prefs.bankMode == 'true' ) {
    this.controller.get('BankMoney').style.visibility = "visible";
  }
  else this.controller.get('BankMoney').style.visibility = "hidden";

		// turn button
  this.turnButtonModel = {
    buttonLabel : 'Roll',
    buttonClass : '',
    disable : false
  };
  this.controller.setupWidget('TurnButtonID',{},this.turnButtonModel);
  Mojo.Event.listen(this.controller.get('TurnButtonID'), Mojo.Event.tap, this.turnButtonAction.bind(this));
  this.controller.get('TurnButtonID').style.visibility = "hidden";

		// shaking can also roll dice
  this.controller.listen(document, 'shaking', this.turnButtonAction.bindAsEventListener(this));

		// purchase button
  this.purchaseModel = {
    buttonLabel : 'Pay',
    buttonClass : '',
    disable : false
    };
  this.controller.setupWidget('PurchaseID',{}, this.purchaseModel);
  Mojo.Event.listen(this.controller.get('PurchaseID'), Mojo.Event.tap, this.makePayment.bind(this));

		// close property button
  this.controller.setupWidget('ClosePropertyID',
    {},
    this.closePropertyModel = {
      buttonLabel : 'x',
      buttonClass : 'smallButton',
      disable : false
    });
  Mojo.Event.listen(this.controller.get('ClosePropertyID'), Mojo.Event.tap, this.closeProperty.bind(this));

		// properties button
  this.PropertiesButtonModel = {
    buttonLabel : 'Assets',
    buttonClass : 'greenButton',
    disable : false
  };
  this.PropertiesButtonAtt = { };
  this.controller.setupWidget('PropertiesButtonID',this.PropertiesButtonAtt,this.PropertiesButtonModel);
  Mojo.Event.listen(this.controller.get('PropertiesButtonID'), Mojo.Event.tap, this.openPropsStage.bind(this));

  this.controller.setupWidget('GameInfoScroller', {
    mode: 'vertical'
  }, this.propertyInfoModel = { });
  // this.propertyInfoModel.revealBottom

  //if ( debug ) debugStuff();

  if ( this.checkForWinner() )
    return 1;


  var savedRollCookie = new Mojo.Model.Cookie("savedRoll");
  var savedRoll = savedRollCookie.get();

		// we haven't rolled yet
  if ( savedRoll == undefined ) {
    this.resetScreen();
    //debugMessage("beginning of turn")
    if ( playerArray[curPlayer].jailstate > 0 )
      this.inJail();
    else if ( isComputer(curPlayer) )
      playturn.delay(1, this);
    else
      this.setTurnButton('roll');
  }
  else {
    this.printInfo(playerArray[curPlayer].playerName + " already rolled");
    this.assetsButton();
    this.afterMove();
  }
}

BoardAssistant.prototype.setTurnButton = function(action) {
try {
  //debugMessage("setTurnButton: " + action);
  if ( action == 'none' ) {
    this.controller.get('TurnButtonID').style.visibility = "hidden";
  }
  else if ( isComputer(curPlayer) ) {
    if ( action == "endturn" && prefs.disableEndTurn != "true" ) {
        this.turnButtonModel.buttonLabel = "Continue";
        this.controller.modelChanged(this.turnButtonModel, this);
        this.controller.get('TurnButtonID').style.visibility = "visible";
    }
  }
  else if ( playerArray[curPlayer].doubleRolls || action == "roll" ) {
    if ( playerArray[curPlayer].stillowe && playerArray[curPlayer].stilloweto != -2 ) {
      this.printInfo(playerArray[curPlayer].playerName + " still owes $" + playerArray[curPlayer].stillowe);
      this.controller.get('TurnButtonID').style.visibility = "hidden";
      this.setPurchaseButton('pay');
    }
    else {
      this.turnButtonModel.buttonLabel = "Roll";
      this.controller.modelChanged(this.turnButtonModel, this);
      this.controller.get('TurnButtonID').style.visibility = "visible";
    }
  }
  else if ( action == "endturn" ) {
    if ( playerArray[curPlayer].stillowe ) {
      this.printInfo(playerArray[curPlayer].playerName + " still owes $" + playerArray[curPlayer].stillowe);
      this.controller.get('TurnButtonID').style.visibility = "hidden";
      this.setPurchaseButton('pay');
    }
    else {
      this.turnButtonModel.buttonLabel = "Continue";
      this.controller.modelChanged(this.turnButtonModel, this);
      this.controller.get('TurnButtonID').style.visibility = "visible";
    }
  }
} catch(x) { debugMessage("Exception in set turn button: " + x); }
}

BoardAssistant.prototype.openPropsStage = function(event) {
  this.firstValue = this.PropertiesButtonModel.original;
  this.controller.stageController.pushScene('props',this.firstValue);
}

playturn = function(thisObj) {
  //debugMessage("playturn");
  if ( ! thisObj.pause )
    thisObj.rollDice();
}

BoardAssistant.prototype.computerSettleDebts = function(player) {
try {
		// settle debts is a computer player function.  if it was run on a human player then return.
  if ( ! isComputer(player) ) return 0;

		// stillowe is  away of setting up a payment without having to deal with the payoff yet.
		// take care of it here.
  if ( playerArray[player].stillowe ) {
    if ( playerArray[player].money < playerArray[player].stillowe ) {
      this.printInfo(playerArray[player].playerName + " is trying to raise $" + playerArray[player].stillowe );
      if ( ! this.autoRaiseMoney(player, playerArray[player].stillowe) ) {
        this.bankruptPlayer(player);
        return 1;
      }
    }

    this.ballanceStillOwe(player);
  }

		// pay off debts
  if ( prefs.complexDebts == 'true' ) {
    if ( playerArray[player].debt && playerArray[player].money >= playerArray[player].debt ) {
      playerArray[player].money -= playerArray[player].debt;
      playerArray[player].debt = 0;
      this.printInfo(playerArray[player].playerName + " pays off his debts");
    }
  }

  this.printMoney();
} catch(x) { debugMessage("Exception in settle debts: " + x); }
}

BoardAssistant.prototype.propertiesIWant = function(player, needed) {
try {
  //debugMessage("start propertiesIWant, needed: " + needed);
		// properties are my properties
  var properties = listOwnedProperties(player);
  var iwant = [];
  var asked = -1;
  //this.printInfo("checking for tradeable properties");
  for ( var i=0; i< properties.length; i++ ) {
		// property is the current property
    property = properties[i];
		// if it's already my monopoly then don't do anything
    if ( isMonopoly(property) ) continue;
    var myPropCount = countOwnedPropsInMonopoly(property);
    if ( myPropCount ) {
		// at this point we know it's a monopoly property
      var monopoly = getMonopoly(property);
      //debugMessage("monopoly has: " + monopoly.length + ", I have: " + myPropCount + ", looking for: " + needed);
      if ( monopoly.length - myPropCount >= needed ) {
		// go through each prop in monopoly to see if we can trade for them
        for ( var n=0; n<monopoly.length; n++ ) { propertyn = monopoly[n];
		// if we already have this property in our list then skip
          if ( inArray(propertyn, iwant) ) break;
          //debugMessage("property is not yet in the list");

          otherOwner = propertyOwner[propertyn].owner;

          //debugMessage("property is owned by: "+ otherOwner);
          if ( otherOwner == undefined ) continue;

		// if it's curPlayer's property then go to next property
          //debugMessage("otherowner: " + otherOwner + ", player: " + player);
          if ( otherOwner == player ) continue;


		// if other owner is a human then test frequency
		// this needs to be here, and not around autoTrade because
		// human can always offer trades, and it's unfair if computers
		// aren't tading at all.
          if ( ! isComputer(otherOwner) ) {
            var rand = Math.random() * 10;
            debugMessage("trade frequency: " + prefs.computerOffersTrades + " < " + rand )
            if ( prefs.computerOffersTrades < rand ) continue;
          }

		// if other owner owns more than one then don't bother
          if ( countOwnedPropsInMonopoly(propertyn, otherOwner) > 1 ) break;

          iwant.push(propertyn);
        }
      }
    }
  }
  //debugMessage("found " + iwant.length + " properties i want");

  return iwant;
} catch(x) { debugMessage("Exception in propertiesIWant: " + x); }
}

BoardAssistant.prototype.autoTrade = function() {
try {
  if ( ! isComputer(curPlayer) ) return [];
		// return 1 if we initiated a trade
  var iwant = [];
  iwant = this.propertiesIWant(curPlayer, 1);
  if ( ! iwant.length ) iwant = this.propertiesIWant(curPlayer, 2);

  if ( iwant.length ) {
    var yourProp = iwant[Math.floor(Math.random() * iwant.length)];
    var yourValue = propertyTradeValue(yourProp, curPlayer );
    var yourOwner = propertyOwner[ yourProp ].owner;
    var properties = listOwnedProperties(curPlayer);
    var myProps = [];
    var myProp = -1;
    var myValue = -1;
		// find curPlayer's property that is worth most to the apponent.
    for ( var i=0; i<properties.length; i++ ) {
      property = properties[i];

		// if this property is my own monopoly then skip it.
      if ( isMonopoly(property, curPlayer) ) continue;

		// if this property is party of the monopoly that I'm trading for then skip.
      if ( sameMonopoly(property, yourProp) ) continue;

		// don't offer railroads or utilities.  it's just annoying.
      if ( isRR(property) || isUtil(property) ) continue;

      //debugMessage("consitering: " + property );
      var toyouValue = propertyTradeValue(property, yourOwner );
      var tomeValue = propertyTradeValue(property, curPlayer );
      //debugMessage("considering: " + property + " : value to me: " + tomeValue + " : to you value : " + toyouValue);
      if ( tomeValue >= toyouValue ) myProps.push(property);
    }

		// if you want any of my properties
    if ( myProps.length ) {
      var myProp = myProps[Math.floor(Math.random() * myProps.length)];
      var myValue = propertyTradeValue(myProp, yourOwner );

		// offerPlayer is going to have to provide more money
      if ( yourValue > myValue ) {
        var offerMoney = yourValue - myValue;

		// does offerPlayer have enough money?
        if ( offerMoney < ( playerArray[ curPlayer ].money + getMortgageableAssets(curPlayer) ) ) {
          if ( ! isComputer(yourOwner) ) {
            var message = "";
            message = propertyArray[myProp][propertyName] + " plus $" + offerMoney + " offered in exchange for " + propertyArray[yourProp][propertyName];
            if ( ! isRR(myProp) && ! isUtil(myProp) ) message += " (you have " + countOwnedPropsInMonopoly(myProp, yourOwner) + " of these properties)";
            this.controller.showAlertDialog({
              onChoose: function(value) {
                if ( value == "accept" ) {
			// if offer player needs to raise money to complete deal...
                  if ( offerMoney > playerArray[ curPlayer ].money ) {
                    if ( autoMortgage(curPlayer, offerMoney) ) {
                      this.printInfo(playerArray[player].playerName + " is mortgaging properties.");
                    }
                    else {
                      this.printInfo(playerArray[curPlayer].playerName + " was unable to raise the money" );
                      return 1;
                    }
                  }
                  if ( performTrade(
                      { player: curPlayer, properties: [ myProp ], money: offerMoney },
                      { player: yourOwner, properties: [ yourProp ] }
                    ) ) {
                    this.printMoney();
                    this.updateTics();
                    this.printInfo(playerArray[curPlayer].playerName + " pays " + playerArray[yourOwner].playerName + " $" + offerMoney );
                  }
                  else {
                    debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
                    this.printInfo("The trade failed...");
                    debugMessage("trade failed: " + playerArray[curPlayer].playerName + " pays " + playerArray[yourOwner].playerName + " $" + offerMoney );
                  }
                }
              },
              title: $L(playerArray[curPlayer].playerName + " offers you a trade"),
              message: message,
              choices:[ {label:$L("Accept"), value:"accept"}, {label:$L("Reject"), value:"reject"} ]
            });
          }
          else {
            if ( offerMoney > playerArray[ curPlayer ].money ) {
              if ( autoMortgage(curPlayer, offerMoney) )
                this.printInfo(playerArray[player].playerName + " is mortgaging properties.");
            }
            if ( performTrade(
                { player: curPlayer, properties: [ myProp ], money: offerMoney },
                { player: yourOwner, properties: [ yourProp ] }
              ) ) {
              this.printInfo(playerArray[curPlayer].playerName + " traded " + propertyArray[myProp][propertyName] + " plus $" + offerMoney + " for " + playerArray[yourOwner].playerName + "'s " + propertyArray[yourProp][propertyName]);
              this.printMoney();//this.controller.get('money').update("$" + playerArray[curPlayer].money);
              this.updateTics();
            }
            else {
              debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
              debugMessage( "trade failed: " + playerArray[curPlayer].playerName + " traded " + propertyArray[myProp][propertyName] + " plus $" + offerMoney + " for " + playerArray[yourOwner].playerName + "'s " + propertyArray[yourProp][propertyName]);
            }
          }
          return 1;
        }
		// player doesn't have enough money
        else if ( ( yourValue - myValue ) < ( playerArray[ curPlayer ].money * 1.5 ) ) {
          if ( ! isComputer(yourOwner) )
            this.printInfo(playerArray[yourOwner].playerName + " rejected trade of " + propertyArray[myProp][propertyName] + " plus $" + playerArray[ curPlayer ].money + " for " + propertyArray[yourProp][propertyName]);
        }
      }
		// requestPlayer is going to need to provide money
      else if ( myValue > yourValue ) {
        if ( prefs.complexDebts == 'true' && playerDebt(curPlayer) ) {
          debugMessage("player already owes money, skipping");
          return 1;
        }
        var requestMoney = myValue - yourValue;
        if ( requestMoney < playerArray[ yourOwner ].money ) {
          if ( ! isComputer(yourOwner) ) {
            var message = "";
            message = propertyArray[myProp][propertyName] + " offered in exchange for " + propertyArray[yourProp][propertyName] + " plus $" + requestMoney;
            if ( ! isRR(myProp) && ! isUtil(myProp) ) message += " (you have " + countOwnedPropsInMonopoly(myProp, yourOwner) + " of these properties)";
            this.controller.showAlertDialog({
              onChoose: function(value) {
                if ( value == "accept" ) {
                  // no mortgage here because it is the human player owes the money
                  if ( performTrade(
                      { player: curPlayer, properties: [ myProp ] },
                      { player: yourOwner, properties: [ yourProp ], money: requestMoney },
                      value
                    ) ) {
                    this.printMoney();//this.controller.get('money').update("$" + playerArray[curPlayer].money);
                    this.updateTics();
                    this.printInfo( playerArray[yourOwner].playerName + " pays " + playerArray[curPlayer].playerName + " $" + requestMoney);
                  }
                  else {
                    this.printInfo(playerArray[yourOwner].playerName + " doesn't have that much money");
                    debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
                    debugMessage("trade failed: " + playerArray[yourOwner].playerName + " pays " + playerArray[curPlayer].playerName + " $" + requestMoney);
                    }
                }
              },
              title: $L(playerArray[curPlayer].playerName + " offers you a trade"),
              message: message,
              choices:[ {label:$L("Accept"), value:"accept"}, {label:$L("Reject"), value:"reject"} ]
            });
          }
          else {
            if ( performTrade(
                { player: curPlayer, properties: [ myProp ] },
                { player: yourOwner, properties: [ yourProp ], money: requestMoney }
              ) ) {
              this.printInfo(playerArray[curPlayer].playerName + " traded " + propertyArray[myProp][propertyName] + " for " + playerArray[yourOwner].playerName + "'s " + propertyArray[yourProp][propertyName] + " plus $" + requestMoney );
              this.printMoney();//this.controller.get('money').update("$" + playerArray[curPlayer].money);
              this.updateTics();
            }
            else {
              debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
              debugMessage("trade failed: " + playerArray[curPlayer].playerName + " traded " + propertyArray[myProp][propertyName] + " for " + playerArray[yourOwner].playerName + "'s " + propertyArray[yourProp][propertyName] + " plus $" + requestMoney );
            }
          }
          return 1;
        }
        else if ( requestMoney < ( playerArray[ yourOwner ].money * 1.5 ) ) {
          if ( isComputer(yourOwner) )
            this.printInfo(playerArray[curPlayer].playerName + " rejected trade of " + propertyArray[myProp][propertyName] + " for " + playerArray[yourOwner].playerName + "'s " + propertyArray[yourProp][propertyName] + " plus $" + playerArray[ yourOwner ].money);
        }
      }
    }
    else {
      //debugMessage("didn't fine anything to trade " + myProp);
      //if ( ( yourValue - playerArray[curPlayer].money ) + playerDebt(curPlayer) > prefs.maxDebt ) return 1;
      if ( yourValue < ( playerArray[curPlayer].money + getMortgageableAssets(curPlayer) ) ) {
        if ( ! isComputer(yourOwner) ) {
          this.controller.showAlertDialog({
            onChoose: function(value) {
              if ( value == "accept" ) {
                if ( yourValue > playerArray[ curPlayer ].money ) {
                  if ( autoMortgage(curPlayer, yourValue) ) {
                    this.printInfo(playerArray[player].playerName + " is mortgaging properties.");
                  }
                  else {
                    this.printInfo(playerArray[curPlayer].playerName + " was unable to raise the money" );
                    debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
                    debugMessage( playerArray[curPlayer].playerName + " was unable to raise " + yourValue );
                    return 1;
                  }
                }
                if ( performTrade(
                    { player: curPlayer, money: yourValue },
                    { player: yourOwner, properties: [ yourProp ] }
                  ) ) {
                  this.printMoney();//this.controller.get('money').update( "$" + playerArray[curPlayer].money );
                  this.updateTics();
                  this.printInfo( playerArray[curPlayer].playerName + " pays " + playerArray[yourOwner].playerName + " $" + yourValue);
                }
                else {
                  debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
                  this.printInfo("trade failed" );
                  debugMessage("trade failed: " + playerArray[curPlayer].playerName + " pays " + playerArray[yourOwner].playerName + " $" + yourValue);
                }
              }
            },
            title: $L(playerArray[curPlayer].playerName + " offers you a trade"),
            message: $L('$' + yourValue + " offerred in exchange for " + propertyArray[yourProp][propertyName]),
            choices:[ {label:$L("Accept"), value:"accept"}, {label:$L("Reject"), value:"reject"} ]
          });
        }
        else {
          if ( yourValue > playerArray[ curPlayer ].money ) {
            if ( autoMortgage(curPlayer, yourValue) )
              this.printInfo(playerArray[curPlayer].playerName + " is mortgaging properties.");
          }
          if ( performTrade(
              { player: curPlayer, money: yourValue },
              { player: yourOwner, properties: [ yourProp ] }
                ) ) {
            this.printInfo(playerArray[curPlayer].playerName + " bought " + propertyArray[yourProp][propertyName] + " from " + playerArray[yourOwner].playerName + " for $" + yourValue);
            this.printMoney();//this.controller.get('money').update( "$" + playerArray[curPlayer].money );
            this.updateTics();
          }
          else {
            debugMessage( "mortgagable assets: " + getMortgageableAssets(curPlayer) + ", money: " + playerArray[curPlayer].money );
            debugMessage("trade failed: " + playerArray[curPlayer].playerName + " bought " + propertyArray[yourProp][propertyName] + " from " + playerArray[yourOwner].playerName + " for $" + yourValue);
          }
        }
        return 1;
      }
      else if ( yourValue < ( playerArray[curPlayer].money * 1.5 ) ) {
        if ( isComputer(yourOwner) )
          this.printInfo(playerArray[yourOwner].playerName + " rejects " + playerArray[curPlayer].playerName + " offer of $" + playerArray[curPlayer].money + " for " + propertyArray[yourProp][propertyName]);
      }
      else {
        this.printInfo(playerArray[curPlayer].playerName + " wants " + propertyArray[yourProp][propertyName]);
      }
    }
  }
  return 0;
} catch(x) { debugMessage("Exception in autotrade: " + x); }
}

BoardAssistant.prototype.autoRaiseMoney = function(player, money) {
try {
  if ( playerArray[player].money >= money ) return 1;

  //this.printInfo(playerArray[player].playerName + " is trying to raise $" + money);
  var properties = listOwnedProperties(player);
  if ( ! properties.length ) return 0;

  if ( mortgageAll(player, money) ) {
    this.printInfo(playerArray[player].playerName + " is mortgaging properties.");
    this.updateHouses();
    return 1;
  }

  if ( sellHousesAndMortgage(player, money) ) {
    this.printInfo(playerArray[player].playerName + " is selling houses.");
    this.updateHouses();
    return 1
  }
  debugMessage("player was unable to raise money")

  this.updateHouses();
  if ( playerArray[player].money > money ) return 1;

  return 0;
} catch(x) { debugMessage("Exception in auto raise money: " + x); }
}

BoardAssistant.prototype.bankruptPlayer = function(player) {
try {
  if ( playerArray[player].stillowe ) {
                // if you owed it to a player...
    if ( playerArray[player].stilloweto >= 0 ) {
                // player owes another player
      this.printInfo(playerArray[player].playerName + " pays " + playerArray[ playerArray[player].stilloweto ].playerName + " $" + playerArray[player].money + " of $" + playerArray[player].stillowe );
      playerArray[ playerArray[player].stilloweto ].money += playerArray[player].money;
    }
    else if ( playerArray[player].stilloweto  == -3 ) {
      this.printInfo(playerArray[player].playerName + " pays $" + playerArray[player].money + " of $" + playerArray[player].stillowe );
      this.updateFreeParking(playerArray[player].money);
    }
                // otherwise pay bank
    else {
      this.printInfo(playerArray[player].playerName + " pays $" + playerArray[player].money + " of $" + playerArray[player].stillowe );
    }
  }

  clearSinglePlayer(player);
  playerArray[player].bankrupt = 1;
  playerArray[player].money = 0;

  properties = listOwnedProperties(player);
  for ( var i=0; i<properties.length; i++ ) {
    property = properties[i];
    clearProperty(property);
  }

  if ( prefs.removeBankruptPieces == "true" ) this.controller.get("character"+player).style.visibility = "hidden";
  this.updateTics();
  this.updateHouses();

  this.printInfo(playerArray[player].playerName + " is bankrupt");

			// create a new player
  if ( prefs.bankMode == 'true' ) {
    var badplayer = true;
    var newplayer = null;
    var count = 0;
    while ( badplayer ) {
      if ( count > 15 ) break;
      count++;
      badplayer = false;
      newplayer = Math.floor( Math.random() * playerArray.length );
      //debugMessage("newplayer: " + newplayer);
      if ( ! isComputer(newplayer) ) badplayer = true;
      for ( var i=0; i<playerList.length; i++ )
        if ( playerList[i] == newplayer ) badplayer = true;
    }
      
    if ( ! badplayer ) {
      for ( var i=0; i<prefs.numPlayers; i++ )
        if ( curPlayer == playerList[i] )
          playerList[i] = newplayer;
      curPlayer = newplayer;
      playerArray[player].bankrupt = 0;
      playerArray[player].money = prefs.startMoney;
      this.printInfo( playerArray[newplayer].playerName + " has entered the game" );
      //debugMessage( playerArray[newplayer].playerName + " has entered the game" );
    }
    //else {
    //  debugMessage( "could not find a new player to add" );
    //}
  }

  this.setTurnButton('endturn');
} catch(x) { debugMessage("Exception in bankrupt player: " + x); }
}

BoardAssistant.prototype.autoUnmortgage = function() {
		// unmortgage properties
  var properties = listOwnedProperties(curPlayer);
  for ( var i=0; i<properties.length; i++ ) {
    if ( playerArray[curPlayer].money < 100 ) return 0;
    if ( propertyOwner[properties[i]].propertyMortgaged ) {
      if ( ! unmortgageProperty(properties[i]) )
        this.printInfo( playerArray[curPlayer].playerName + " is unmortgaging " + propertyArray[properties[i]][propertyName] );
    }
  }
}

BoardAssistant.prototype.autoBuyHouses = function(player) {
try {
  tmpArray = [];
  for ( var i=0; i<propertyArray.length; i++ ) tmpArray[i] = 0;
		// buy houses
  var count = 0;
  var properties = listOwnedProperties(player);
  for ( var i=0; i<properties.length; i++ ) {
    property = properties[i];
    if ( ! isMonopoly(property, player) ) continue;

    if ( ! prefs.complexDebts == "true" )
      if ( playerArray[player].money < 100 ) break;
    //else
      //if ( playerDebt(player) > prefs.maxDebt ) break;

    while ( propertyOwner[property].ownedHouses < 5 ) {
      if ( ! prefs.complexDebts == "true" )
        if ( playerArray[player].money < 100 ) break;
      //else
        //if ( playerDebt(player) > prefs.maxDebt ) break;
      var monopoly = getMonopoly(property);
      for ( var j=(monopoly.length - 1); j>=0; j-- ) {
        if ( ! prefs.complexDebts == "true" )
          if ( playerArray[player].money < 100 ) break;
        //else
          //if ( playerDebt(player) > prefs.maxDebt ) break;
        if ( buyHouse(monopoly[j]) ) {
          this.printBoughtHouses(tmpArray);
          this.printMoney();
          this.updateHouses();
          return 0;
        }
        tmpArray[monopoly[j]]++
      }
    }
  }
  this.printBoughtHouses(tmpArray);
  this.printMoney();
  this.updateHouses();
} catch(x) { debugMessage('Exception in auto buy houses: ' + x); }
}

BoardAssistant.prototype.printBoughtHouses = function(tmpArray) {
  for ( var i=0; i<tmpArray.length; i++ ) {
    if ( tmpArray[i] > 0 )
      this.printInfo( playerArray[curPlayer].playerName + " bought " + tmpArray[i] + " houses for " + propertyArray[i][propertyName] );
  }
}

BoardAssistant.prototype.turnButtonAction = function(event) {
  if ( this.controller.get('TurnButtonID').style.visibility == "hidden" )
    return 1;

  this.setTurnButton('none');

  if ( this.turnButtonModel.buttonLabel == "Roll" )
    this.rollDice();
  else if ( this.turnButtonModel.buttonLabel == 'Continue' )
    this.endTurn();
}

BoardAssistant.prototype.rollDice = function(event) {
try {
  //debugMessage("rollDice");
  this.controller.get('CardDiv').style.visibility = "hidden";
  this.setTurnButton('none');

  if ( playerArray[curPlayer].jailstate > 0 && playerArray[curPlayer].jailturns >= 3 ) return 1;
  if ( playerArray[curPlayer].bankrupt ) return 1;

  this.dice1 = Math.ceil(Math.random() * 6);
  this.dice2 = Math.ceil(Math.random() * 6);
  var savedRollCookie = new Mojo.Model.Cookie("savedRoll");
  savedRollCookie.put([this.dice1, this.dice2]);

  this.diceTotal = this.dice1 + this.dice2;
  if ( alwaysRoll ) this.diceTotal = alwaysRoll;
  this.controller.get('DiceValue').update('<img src="images/'+this.dice1+'.png"><img src="images/'+this.dice2+'.png">');

  this.printInfo( "<b>" + playerArray[curPlayer].playerName + " rolled " + this.diceTotal + "</b>");

		// if we're in jail and not doubles then...
  if ( playerArray[curPlayer].jailstate > 0 ) {
    if ( this.dice1 == this.dice2 ) {
		// this was made visible by "injail"
      this.printInfo(playerArray[curPlayer].playerName+" got out of jail by rolling doubles");
      playerArray[curPlayer].jailstate = 0;
      playerArray[curPlayer].jailturns = 0;
    }
    else {
		// since we aren't going to "move player" we need to handle the end turn button.
      //this.controller.get('EndTurnID').style.visibility = "visible";
      this.printInfo(playerArray[curPlayer].playerName+" did not roll doubles");
      this.goToJail();
		// skip the rest of the function
      return 0;
    }
  }

		// if it's doubles...
  if ( this.dice1 == this.dice2 ) {
		// count the turns
    playerArray[curPlayer].doubleRolls++;
		// if 3 doubles then go to jail and exit.
    if ( playerArray[curPlayer].doubleRolls >= 3 ) {
      this.printInfo("<b>doubles rolled 3 times.  Go to jail");
      this.goToJail();
      return 0;
    }
  }
  else
    playerArray[curPlayer].doubleRolls = 0;

  if ( playerArray[curPlayer].doubleRolls )
    this.printInfo("doubles rolled " + playerArray[curPlayer].doubleRolls + " times.");

		// finally move the player
  //debugMessage("show steps: " + prefs.showSteps);
  if ( prefs.showSteps == "true" ) {
    var newposition = playerArray[curPlayer].position + this.diceTotal;
    var stepposition = playerArray[curPlayer].position;
    if ( newposition > 39 ) {
      newposition -= 40;
      stepposition -= 40;
    }
    this.stepPlayer(stepposition, newposition);
  }
  else {
    this.movePlayer(playerArray[curPlayer].position + this.diceTotal);
  }
} catch(x) { debugMessage('Exception in roll dice: ' + x); }
}

BoardAssistant.prototype.updateFreeParking = function(money) {
  freeParkingMoney += money;
  if ( prefs.payToFreeParking == "true" )
    this.controller.get('freeparking').update("$" + freeParkingMoney);
}

BoardAssistant.prototype.ballanceStillOwe = function(player) {
  if ( ! playerArray[player].stillowe ) return 1;

  var money = playerArray[player].stillowe;
  var to = playerArray[player].stilloweto;

  if ( playerArray[player].money >= money ) {
                // loan
    if ( to == -2 ) {
      playerArray[curPlayer].money -= money;
      bankMoney += money;
      playerArray[player].stillowe = 0;
      playerArray[player].stilloweto = 0;
      this.printInfo(playerArray[curPlayer].playerName + " paid $" + money + " for loan payment");
    }
                // to free parking
    else if ( to == -3 ) {
      playerArray[curPlayer].money -= money;
      this.updateFreeParking(money);
      playerArray[player].stillowe = 0;
      playerArray[player].stilloweto = 0;
      this.printInfo(playerArray[curPlayer].playerName + " paid $" + money);
    }
                // to jail
    else if ( to == -6) {
      if ( this.makeJailPayment() ) {
        playerArray[player].stillowe = 0;
        playerArray[player].stilloweto = 0;
      }
    }
                // other
    else if ( to < 0 ) {
      playerArray[curPlayer].money -= money;
      this.printInfo(playerArray[curPlayer].playerName + " paid $" + money);
      playerArray[player].stillowe = 0;
      playerArray[player].stilloweto = 0;
    }
                // to player
    else {
      playerArray[to].money += money;
      playerArray[curPlayer].money -= money;
      this.printInfo(playerArray[curPlayer].playerName + " paid $" + money + " to " + playerArray[to].playerName);
      playerArray[player].stillowe = 0;
      playerArray[player].stilloweto = 0;
    }

    saveDynamicObjects();
    this.printMoney();
    return 1;
  }
  else return 0;
}

BoardAssistant.prototype.makeJailPayment = function(event) {
  //debugMessage("makeJailPayment");

  if ( playerArray[curPlayer].jailcards > 0 ) {
    playerArray[curPlayer].jailcards--;
    playerArray[curPlayer].jailstate = 0;
    playerArray[curPlayer].jailturns = 0;
    this.printInfo(playerArray[curPlayer].playerName + " used a get out of Jail Free Card");
    this.setTurnButton('roll');
    this.setPurchaseButton('check');
    return 1;
  }

  if ( isComputer(curPlayer) )
    this.autoRaiseMoney(curPlayer, 50);

  if ( playerArray[curPlayer].money >= 50 ) {
    playerArray[curPlayer].money -= 50;
    this.printMoney();
    this.updateFreeParking(50);
    playerArray[curPlayer].jailstate = 0;
    playerArray[curPlayer].jailturns = 0;
    this.printInfo( "fine paid" );
    this.setTurnButton('roll');
    this.setPurchaseButton('check');
    return 1;
  }
  return 0;
}

BoardAssistant.prototype.setPurchaseButton = function(mode) {
  if ( isComputer(curPlayer) ) {
    this.controller.get('PurchaseID').style.visibility = "hidden";
  }
  else if ( mode == 'clear' ) {
    this.controller.get('PurchaseID').style.visibility = "hidden";
  }
  else if ( playerArray[curPlayer].stillowe ) {
    //debugMessage("pay for stillowe: "+ playerArray[curPlayer].stillowe);
    this.purchaseModel.buttonLabel = "Pay";
    this.controller.modelChanged(this.purchaseModel, this);
    this.controller.get('PurchaseID').style.visibility = "visible";
  }
  else if ( mode == 'check' ) {
    this.controller.get('PurchaseID').style.visibility = "hidden";
  }
  else if ( mode == 'buy' ) {
    this.purchaseModel.buttonLabel = "Buy";
    this.controller.modelChanged(this.purchaseModel, this);
    this.controller.get('PurchaseID').style.visibility = "visible";
  }
  else if ( mode == 'pay' ) {
    this.purchaseModel.buttonLabel = "Pay";
    this.controller.modelChanged(this.purchaseModel, this);
    this.controller.get('PurchaseID').style.visibility = "visible";
  }
}

BoardAssistant.prototype.makePayment = function(event) {
try {
  //debugMessage("make payment");
		// owe money
  if ( playerArray[curPlayer].stillowe ) {
    if ( isComputer(curPlayer) )
      if ( ! this.autoRaiseMoney(curPlayer, playerArray[curPlayer].stillowe) )
        this.bankruptPlayer(curPlayer);

    if ( this.ballanceStillOwe(curPlayer) ) {
      this.setPurchaseButton('check');
      this.setTurnButton('endturn');
    }
  }
		// purchaseable property
  else if ( propertyArray[ playerArray[curPlayer].position ][price] > 0 && propertyOwner[ playerArray[curPlayer].position ].owner == null ) {
    if ( prefs.complexDebts == "true" && ! isComputer(curPlayer) )
      this.buyPropertyQuestion(playerArray[curPlayer].position, curPlayer);
    else
      this.buyProperty(playerArray[curPlayer].position, curPlayer);
  }
		// in jail
  else if ( playerArray[curPlayer].jailstate > 0 ) {
    if ( this.makeJailPayment() )
      this.setPurchaseButton('check');
  }
} catch(x) { debugMessage('Exception in make payment: ' + x); }
}

BoardAssistant.prototype.buyPropertyQuestion = function(property, player) {
  if ( isComputer(player) ) {
    return 0;
  }

                // change purchase model to the one with "buy" as the button label
  if ( prefs.complexDebts == "true" ) {
		// if they have more than the property price than they can buy
    if ( playerArray[player].money >= propertyArray[property][price] ) {
      var choices = [
			{label:$L("buy"), value:"buy"},
                        {label:$L("morgage"), value:"mortgage"},
                        {label:$L("no"), value:"no"} ];
    }
		// only offer to mortgage if they don't have enough money to buy outright
    else if ( playerArray[player].money >= propertyArray[property][price] * prefs.moneyDown ) {
      var choices = [
                        {label:$L("morgage"), value:"mortgage"},
                        {label:$L("no"), value:"no"} ];
    }
    else
      return 0;
  }
		// if it's no complex debts then they can either buy or no
  else {
    if ( playerArray[player].money >= propertyArray[property][price] ) {
      var choices = [
			{label:$L("yes"), value:"buy"},
			{label:$L("no"), value:"no"} ];
    }
    else
      return 0;
  }

  this.controller.showAlertDialog({
    onChoose: function(value) {
      if ( value == "buy" ) {
        this.buyProperty(property, player);
      }
      else if ( value == "mortgage" ) {
        mortgageProperty(property, player);
        if ( ! this.buyProperty(property, player) )
          unmortgageProperty(property, player);
      }
    },
    title: $L("Do you want to buy " + propertyArray[property][propertyName] + " for $" + propertyArray[property][price] + "?"),
    choices: choices
  });
}

BoardAssistant.prototype.printMoney = function(event) {
  if ( prefs.complexDebts == "true" ) {
    var debt = playerDebt(curPlayer);
    this.controller.get('money').update( "$" + playerArray[curPlayer].money + " - $" + debt );
    this.controller.get('BankMoney').update( "Bank: $" + bankMoney );
  }
  else {
    this.controller.get('money').update( "$" + playerArray[curPlayer].money );
  }

}

BoardAssistant.prototype.closeProperty = function(event) {
try {
  this.controller.get('CardDiv').style.visibility = "hidden";
} catch(x) { debugMessage('Exception in close property: ' + x); }
}

BoardAssistant.prototype.printInfo = function( text ) {
  var curInfo = this.controller.get('GameInfo').innerHTML;
  if ( curInfo == null ) curInfo = "";
  curInfo += text + "<br>";
  this.controller.get('GameInfo').update('<div class="subtext">' + curInfo + '</div>');
  //this.controller.get("GameInfoScroller").mojo.revealBottom(0);
}

BoardAssistant.prototype.updateTics = function() {
  var tics = "";
  for ( var i=0; i<propertyArray.length; i++ )
  {
    if ( propertyOwner[i].owner == curPlayer )
      tics += '<div style="position:absolute;' + propertyArray[i][ticposition] + 'background-color:' + propertyArray[i][propertyColor] + ';height:5px;width:10px;"></div>';
  }
  this.controller.get('propertyTics').update(tics);
}

BoardAssistant.prototype.nextPlayer = function() {
try {
  for ( var i=0; i<prefs.numPlayers; i++ ) {
    //debugMessage("curPlayer: " + curPlayer + ", i: " + i + ", prefs.numPlayers: " + prefs.numPlayers);
    if ( curPlayer == playerList[i] ) {
      if ( i >= prefs.numPlayers - 1 ) {
        curPlayer = playerList[0];
        return 0;
      }
      else {
        curPlayer = playerList[i+1];
        return 0;
      }
    }
  }
  curPlayer = playerList[0];
  //debugMessage("could not pick the next player");
  this.printInfo( "Could not pick next player.  This is a serious bug!" );
  return 1;
} catch(x) { debugMessage('Exception in next turn: ' + x); }
}

BoardAssistant.prototype.checkForWinner = function() {
  var count = 0;
  for ( var i=0; i<prefs.numPlayers; i++ ) {
    player = playerList[i];
    if ( ! playerArray[player].bankrupt ) count++;
  }
  if ( count <= 1 ) {
		// if there is only one non-bankrupt player then he wins.
    /*
    this.controller.showAlertDialog({
      onChoose: function(value) {},
      title: $L(playerArray[curPlayer].playerName + " wins!"),
      choices:[
        {label:$L("OK"), value:""}
      ]
    });
    */
    popup(this, playerArray[curPlayer].playerName + " wins!");
    this.printInfo( playerArray[curPlayer].playerName + " wins!");
    this.controller.get('TurnButtonID').style.visibility = "hidden";
    this.controller.get('PurchaseID').style.visibility = "hidden";
    /*
    if ( isComputer(curPlayer) ) {
      this.controller.get('PropertiesButtonID').style.visibility = "hidden";
      this.myMenuModel.items[1]['disabled'] = true;
    }
    else {
      this.controller.get('PropertiesButtonID').style.visibility = "visible";
      this.myMenuModel.items[1]['disabled'] = false;
    }
    this.controller.modelChanged(this.myMenuModel, this);
    */
    saveDynamicObjects();
    return 1;
  }

  return 0;
}

endTurnWrapper = function(thisObj) {
  thisObj.endTurn();
}

BoardAssistant.prototype.endTurn = function(event) {
try {
  //debugMessage("endturn");
		// first clear old turn data out
  clearDiceCookie();
  this.controller.get('GameInfo').update( "" );
  this.controller.get('DiceValue').update('');


		// set curPlayer to next player
  this.nextPlayer();
  while ( playerArray[curPlayer].bankrupt )
    this.nextPlayer();

  saveDynamicObjects();

  if ( this.checkForWinner() )
    return 1;

  this.beforeMove();

  if ( playerArray[curPlayer].jailstate > 0 )
    this.inJail();
  else if ( isComputer(curPlayer) )
    playturn.delay(1, this);
  else
    this.setTurnButton('roll');

} catch(x) { debugMessage('Exception in end turn: ' + x); }
}

BoardAssistant.prototype.assetsButton = function() {
  if ( prefs.bankMode == 'true' ) {
  }
  else if ( isComputer(curPlayer) ) {
    this.controller.get('PropertiesButtonID').style.visibility = "hidden";
    this.myMenuModel.items[1]['disabled'] = true;
    this.controller.modelChanged(this.myMenuModel, this);
  }
  else {
    this.controller.get('PropertiesButtonID').style.visibility = "visible";
    this.myMenuModel.items[1]['disabled'] = false;
    this.controller.modelChanged(this.myMenuModel, this);
  }
}

BoardAssistant.prototype.resetScreen = function() {
  //debugMessage("reset screen");
  this.printInfo(playerArray[curPlayer].playerName + "'s turn");
  this.controller.get('CardDiv').style.visibility = "hidden";
  this.controller.get('PlayerID').update( playerArray[curPlayer].playerName );
  this.printMoney();
  this.printPlayer(curPlayer, playerArray[curPlayer].position);
  this.printCard(playerArray[curPlayer].position);
  this.updateTics();
  this.assetsButton();
  this.setPurchaseButton('check');
}

BoardAssistant.prototype.printPlayer = function(player, position) {
try {

  var leftMargin = 0;
  var topMargin = 7;
  this.controller.get("character" + player).update('<div style="position:absolute;' + propertyArray[position][propertylocation] + 'left-margin:' + leftMargin + 'px;top-margin:' + topMargin + 'px;">' + playerArray[player].icon + '</div>');

} catch(x) { debugMessage('Exception in print player: ' + x); }
}

		// print card
BoardAssistant.prototype.printCard = function(printposition) {
try {
  if ( propertyArray[printposition][propertyName].length > 15 )
    this.controller.get('PropertyName').update( '<span style="font-size:14px;">' + propertyArray[printposition][propertyName] + '</span>' );
  else
    this.controller.get('PropertyName').update( propertyArray[printposition][propertyName] );
  this.controller.get('PropertyColor').style.backgroundColor = propertyArray[printposition][propertyColor];

  var info = "";
  if ( propertyArray[printposition][house[1]] != undefined ) {
    info += "With 0 Houses  $" + propertyArray[printposition][house[0]] + "<br>";
    info += "With 1 House  $" + propertyArray[printposition][house[1]] + "<br>";
    info += "With 2 Houses $" + propertyArray[printposition][house[2]] + "<br>";
    info += "With 3 House $" + propertyArray[printposition][house[3]] + "<br>";
    info += "With 4 House $" + propertyArray[printposition][house[4]] + "<br>";
    info += "With Hotel $" + propertyArray[printposition][house[5]] + "<br>";
  }
  if ( ! prefs.complexDebts == 'true' && propertyArray[printposition][price] != undefined )
    info += "Mortgage Value $" + Math.round( propertyArray[printposition][price] * prefs.mortgageValue ) + "<br>";
  if ( propertyArray[printposition][house[1]] != undefined )
    info += "House cost $" + Math.round( propertyArray[printposition][housePrice] * prefs.housePriceMultiplier ) + "<br>";
  this.controller.get('PropertyInfo').update( info );

  if ( propertyArray[printposition][price] == 0 )
    this.controller.get('PropertyPrice').update( "" );
  else if ( propertyOwner[printposition].owner == curPlayer )
    this.controller.get('PropertyPrice').update( "" );
  else if ( propertyOwner[printposition].owner == null )
    this.controller.get('PropertyPrice').update( "Cost: $" + propertyArray[printposition][price] );
  else {
    var housesOwned = propertyOwner[printposition].ownedHouses;
    var rentfee = this.getRentFee(printposition);
    if ( housesOwned > 0 )
      this.controller.get('PropertyPrice').update( 'Rent: (' + housesOwned + ' houses) $' + rentfee );
    else
      this.controller.get('PropertyPrice').update( 'Rent: $' + rentfee );
  }
} catch(x) { debugMessage('Exception in print card: ' + x); }
}

BoardAssistant.prototype.stepPlayer = function(stepposition, destination) {
  stepPlayerDelayed(this, stepposition, destination);
}

stepPlayerDelayed = function(thisObj, stepposition, destination) {
  if ( killGame )
    return 0;
  stepposition++;
  if ( prefs.showSteps == 'true' && stepposition == 0 )
    thisObj.passGo(destination);

		// if stepposition is greater or equal to destination we're done
  if ( stepposition >= destination ) {
    thisObj.printPlayer(curPlayer, stepposition );
    movePlayerDelayedWrapper.delay(.5, thisObj, destination);
    return 0;
  }
		// if stepposition is less than 0 then we are going to pass go this move
  else if ( stepposition < 0 )
    thisObj.printPlayer(curPlayer, stepposition + 40 );
		// otherwise keep walking
  else
    thisObj.printPlayer(curPlayer, stepposition );

  stepPlayerDelayed.delay(.5, thisObj, stepposition, destination);
}

BoardAssistant.prototype.passGo = function(destination) {
		// go
      if ( playerArray[curPlayer].jailstate > 0 ) {
        return 0;
      }
      else if ( chanceExceptions == "fromcard" ) {
        this.printInfo('Collect $200');
        playerArray[curPlayer].money += 200;
      }
      else if ( prefs.doubleOnGo == "true" && destination == 0 ) {
        playerArray[curPlayer].money += 400;
        this.printInfo("Collect $400");
      }
      else {
        playerArray[curPlayer].money += 200;
        this.printInfo("Pass " + propertyArray[0][propertyName] + " Collect $200");
      }
      this.printMoney();
}

BoardAssistant.prototype.movePlayer = function(newposition) {
  if ( prefs.showSteps == 'true' ) {
    movePlayerDelayedWrapper.delay(1.5, this, newposition);
  }
  else {
    movePlayerDelayedWrapper.delay(0, this, newposition);
  }
}

movePlayerDelayedWrapper = function(thisObj, newposition) {
  thisObj.movePlayerDelayed(newposition);
}

BoardAssistant.prototype.movePlayerDelayed = function(newposition) {
try {
  //debugMessage("move player");

  if ( newposition >= propertyArray.length ) newposition -= propertyArray.length;
  this.printPlayer(curPlayer, newposition);

		// if we passed go then
  if ( playerArray[curPlayer].position > newposition ) {
		// and either we came from a chance card or we don't do steps...
    if ( chanceExceptions || prefs.showSteps != 'true' )
      this.passGo(newposition);
  }

  playerArray[curPlayer].position = newposition;

  this.printCard(playerArray[curPlayer].position);
  this.printInfo("Landed on " + propertyArray[ playerArray[curPlayer].position ][propertyName]);

		//Income Tax
  if ( newposition == 4 ) {
    this.printInfo("Pay 10% or $200");

    var assets = playerArray[curPlayer].money;
    if ( prefs.complexDebts == 'true' ) assets -= playerArray[curPlayer].debt;
    assets += getPropertyAssets(curPlayer) + getHouseAssets(curPlayer);
    var tax = Math.round( assets * .1 );

    if ( tax > 200 ) tax = 200;
    playerArray[curPlayer].money -= tax;
    this.updateFreeParking(tax);
    this.printInfo(playerArray[curPlayer].playerName + " paid $" + tax);
    //this.controller.get('money').update("$" + playerArray[curPlayer].money);
    this.printMoney();
  }
		// jail
  else if ( newposition == 10 ) {
    if ( playerArray[curPlayer].jailstate <= 0 ) this.printInfo("Just Visiting");
  }
		// free parking
  else if ( newposition == 20 ) {
    if ( prefs.payToFreeParking == "true" ) {
      if ( freeParkingMoney ) {
        this.printInfo(playerArray[curPlayer].playerName + " receives $" + freeParkingMoney + " from " + propertyArray[20][propertyName] + "." );
        playerArray[curPlayer].money += freeParkingMoney;
        //this.controller.get('money').update("$" + playerArray[curPlayer].money);
        this.printMoney();
        freeParkingMoney = 0;
        this.updateFreeParking(0);
      }
      else {
        this.printInfo("There is no money in " + propertyArray[20][propertyName] + ".");
      }
    }
  }
  else if ( newposition == 38 ) {
		//Luxery Tax
    this.printInfo("pay $75");
    this.waitForPayment(75, -3);
  }
  else if ( newposition == 30 ) {
		//Go to Jail
    this.goToJail();
    return 0;
  }
  else if ( newposition == 7 || newposition == 22 || newposition == 36 ) {
		//Chance
    var ret = this.pickACard("chance");
    if ( ret == "moved" || ret == "jail" ) return 0;
  }
  else if ( newposition == 2 || newposition ==  17 || newposition == 33 ) {
		//Community Chest
    var ret = this.pickACard("communitychest");
    if ( ret == "moved" || ret == "jail" ) return 0;
  }
  else if ( propertyArray[newposition][price] > 0 ) {
		// not owened yet.
    if ( propertyOwner[newposition].owner == null ) {
      this.printInfo( playerArray[curPlayer].playerName + " can buy " + propertyArray[newposition][propertyName] + " for $" + propertyArray[newposition][price] );
      if ( prefs.displayPropertyCards == 'true' )
        this.controller.get('CardDiv').style.visibility = "visible";
		// if player is human and property is purchaseable then show purchase button
      if ( isComputer(curPlayer) ) {
        this.computerSettleDebts(curPlayer);
        this.buyProperty(newposition, curPlayer);
      }
      else {
        this.buyPropertyQuestion(newposition, curPlayer);
        this.setPurchaseButton('buy');
      }
    }
		// else if property is owned by curPlayer
    else if ( propertyOwner[newposition].owner == curPlayer )
      this.printInfo( playerArray[curPlayer].playerName + " landed on his own property" );
		// else it's owened
    else if ( propertyOwner[newposition].propertyMortgaged && ! prefs.complexDebts == "true" )
      this.printInfo( "property is mortgaged" );
    else if ( prefs.rentInJail == false && playerArray[ propertyOwner[newposition].owner ].jailstate > 0 )
      this.printInfo( "owner of property is in jail" );
    else {
      var rentfee = this.getRentFee(newposition);
      this.printInfo( "Rent is $" + rentfee );
      this.waitForPayment(rentfee, propertyOwner[newposition].owner);
    }
  }
		// if we rolled doubles then we need to go again
  if ( playerArray[curPlayer].doubleRolls ) {
    //debugMessage("doubles!");
    if ( isComputer(curPlayer) )
      playturn.delay(1, this);
    else
      this.setTurnButton('roll');
  }
  else {
    this.afterMove();
  }

} catch(x) { debugMessage("Exception in Player Delayed: " + x); }
}

BoardAssistant.prototype.beforeMove = function() {
  this.resetScreen();
		// firset make sure we aren't negative.  Some cards remove from player's money without checking
  if ( ! this.autoRaiseMoney(curPlayer, 0) )
    this.bankruptPlayer(curPlayer);
		// before move, add loan payments to still owe
  var loanpayment = getLoanPayment(curPlayer);

  if ( loanpayment ) {
    if ( playerArray[curPlayer].money >= loanpayment ) {
      playerArray[curPlayer].money -= loanpayment;
      bankMoney += loanpayment;
      this.printInfo(playerArray[curPlayer].playerName + " pays loan payment of $" + loanpayment );
    }
    else {
      playerArray[curPlayer].stillowe += loanpayment;
      playerArray[curPlayer].stilloweto = -2;
      this.printInfo(playerArray[curPlayer].playerName + " will have to pay $" + loanpayment + " for a loan payment.");
    }
  }

  this.printMoney();
  //debugMessage( playerArray[curPlayer].playerName + " started with $" + playerArray[curPlayer].money + ", mortgagable assets: $" + getMortgageableAssets(curPlayer) );
}

BoardAssistant.prototype.buyProperty = function(property, player) {
try{
  debugMessage(playerArray[curPlayer].playerName + " is buying " + propertyArray[property][propertyName] );
                // if it's not a purchasable property then don't do anything.
  if ( propertyArray[property][price] == 0 ) return 0;
                // if it is owned then don't do anything
  if ( propertyOwner[property].owner != null ) return 0;

                // if player is a computer then try to raise money
  if ( isComputer(player) && propertyArray[property][price] > playerArray[player].money ) {
    if ( prefs.complexDebts == "true" ) {
      var moneyrequired = Math.round(propertyArray[property][price] * prefs.moneyDown);

      if ( moneyrequired > playerArray[player].money ) {
        if ( autoMortgage( player, moneyrequired ) )
          this.printInfo(playerArray[player].playerName + " is mortgaging properties.");
      }

                // complexDebts allows you to mortgage the property before buying
      if ( playerArray[player].money >= propertyArray[property][price] * prefs.moneyDown )
        mortgageProperty(property, player);
    }
    else {
      if ( propertyArray[property][price] > playerArray[player].money ) {
        if ( autoMortgage( player, propertyArray[property][price] ) )
          this.printInfo(playerArray[player].playerName + " is mortgaging properties.");
      }
    }
  }

  if ( playerArray[player].money >= propertyArray[property][price] ) {
    playerArray[player].money -= propertyArray[property][price];
    propertyOwner[property].owner = player;
    this.printMoney();
    this.updateTics();
    this.printHouses(property);
    saveDynamicObjects();
    this.printInfo( 'Bought' );
    this.setPurchaseButton('check');
    return 1;
  }
  else {
    this.printInfo( playerArray[player].playerName + ' was unable to buy ' + propertyArray[ playerArray[player].position ][propertyName] );
    return 0;
  }

  return 0;
} catch(x) { debugMessage('Exception in buy property: ' + x); }
}

BoardAssistant.prototype.afterMove = function() {
try {
  //debugMessage("after move");
  chanceExceptions = "";
		//this may cause problem.  not sure why it's here though.
  //if ( playerArray[curPlayer].jailstate > 0 ) return 0;

  if ( isComputer(curPlayer) ) {
    this.computerSettleDebts(curPlayer);

    //var rand = Math.random() * 10;
    //debugMessage("trade frequency: " + prefs.computerOffersTrades + " > " + rand )
    //if ( prefs.computerOffersTrades > rand )
    this.autoTrade();

    if ( prefs.ComplexDebts ) {
      this.autoBuyHouses(curPlayer);
      this.autoUnmortgage();
    }
    else {
      this.autoUnmortgage();
      this.autoBuyHouses(curPlayer);
    }
  }

  if ( isComputer(curPlayer) && prefs.disableEndTurn == "true" )
    endTurnWrapper.delay(2, this);
  else
    this.setTurnButton('endturn');

  saveDynamicObjects();
} catch(x) { debugMessage("Exception in after move: " + x); }
}

BoardAssistant.prototype.getRentFee = function(property) {
try {
  var rentfee = 0;
  var pOwner = propertyOwner[property].owner;

		// railroad
  //if ( property == 5 || property == 15 || property == 25 || property == 35 ) {
  if ( isRR(property) ) {
    var count = 0;
		// count the railroads
    if ( propertyOwner[5].owner == pOwner ) count++;
    if ( propertyOwner[15].owner == pOwner ) count++;
    if ( propertyOwner[25].owner == pOwner ) count++;
    if ( propertyOwner[35].owner == pOwner ) count++;

    //this.printInfo(count + " railoads are owned by " + playerArray[pOwner].playerName);

    if ( count == 1 )
      rentfee = 25;
    else if ( count == 2 )
      rentfee = 50;
    else if ( count == 3 )
      rentfee = 100;
    else if ( count == 4 )
      rentfee = 200;
    else
      rentfee = 0;

    // if we're here because of chance
    if ( chanceExceptions == "2xRR" ) rentfee = rentfee * 2;
  }
  //else if ( property == 12 || property == 28 ) {
  else if ( isUtil(property) ) {
    var count = 0;
		//count the utilities
    if ( propertyOwner[12].owner == pOwner ) count++;
    if ( propertyOwner[28].owner == pOwner ) count++;

    if ( count == 1 )
      rentfee = 4 * this.diceTotal;
    else if ( count == 2 )
      rentfee = 10 * this.diceTotal;
    else
      rentfee = 0;
  }
  else if ( propertyArray[property][house[0]] != null ) {
    var housesOwned = propertyOwner[property].ownedHouses;
    var rentfee = propertyArray[property][ house[housesOwned] ];
    if ( isMonopoly(property, pOwner) && housesOwned == 0 ) rentfee = rentfee * 2;
    //this.printInfo("owned by " + playerArray[pOwner].playerName);
  }
  return rentfee;
} catch(x) { debugMessage("Exception in rentfee: " + x); }
}

BoardAssistant.prototype.pickACard = function(pile) {
		// bail if we disabled cards
  if ( disableCards == 1 ) return 0;

  var myNum = -1;

  if ( pile == "chance" )
  {
		// if we are out of shuffled cards then re-shuffle
    if ( this.chanceShuffle.length <= 0 )
      this.chanceShuffle = shuffleCards(chanceCards.length);
		// pick a new card
    myNum = this.chanceShuffle.pop();
		// print the card
    //printInfo('<div class=subtext>' + chanceCards[myNum] + '</div>');
    this.printInfo(chanceCards[myNum]);

    switch ( myNum )
    {
      case 0:	// get out of jail
        playerArray[curPlayer].jailcards++;
	break;
      case 1:	// board walk
        // wait until button
        chanceExceptions = "fromcard";
	this.movePlayer(39);
        return "moved";
	break;
      case 2:	// Illilois
        // wait until button
        chanceExceptions = "fromcard";
	this.movePlayer(24);
        return "moved";
	break;
      case 3:	// Building and Loan
	playerArray[curPlayer].money += 150;
	//this.controller.get('money').update("$" + playerArray[curPlayer].money);
        this.printMoney();
        break;
      case 4:	// Elected Chairman
        for (var i=0; i<playerList.length; i++) {
          player = playerList[i];
          if ( player == curPlayer || playerArray[player].bankrupt ) continue;
          playerArray[player].money += 50;
        }
	payment = 50 * ( prefs.numPlayers - 1 );
        this.waitForPayment(payment, -1);
	break;
      case 5:	// street repairs
        var charge = 0;
        for ( var i=0; i<propertyOwner.length; i++) {
          if ( propertyOwner[i].owner != curPlayer ) continue;
          if ( propertyOwner[i].ownedHouses >= 5 )
            charge += 115;
          else if ( propertyOwner[i].ownedHouses > 0 )
            charge += 40 * propertyOwner[i].ownedHouses;
        }
        this.printInfo("total of $" + charge);
        this.waitForPayment(charge, -3);
	break;
      case 6:	// st. charles
        // wait until button
        chanceExceptions = "fromcard";
	this.movePlayer(11);
        return "moved";
	break;
      case 7:	// go
        // wait until button
        chanceExceptions = "fromcard";
	this.movePlayer(0);
        return "moved";
	break;
      case 8:	// school tax
        this.waitForPayment(150, -3);
	break;
      case 9:	// reading
        // wait until button
        chanceExceptions = "fromcard";
	this.movePlayer(5);
        return "moved";
	break;
      case 10:	// go to jail
        // wait until button
        this.goToJail();
        return "jail";
	break;
      case 11:	// pay poor tax
	this.waitForPayment(12, -3);
	break;
      case 12:	// xmas
        playerArray[curPlayer].money += 100;
	this.printMoney();//this.controller.get('money').update("$" + playerArray[curPlayer].money);
	break;
      case 13:	// Parking fee
	this.waitForPayment(15, -3);
	break;
      case 14:	// general repairs
        var charge = 0;
        for ( var i=0; i<propertyOwner.length; i++) {
          if ( propertyOwner[i].owner != curPlayer ) continue;
          if ( propertyOwner[i].ownedHouses >= 5 )
            charge += 100;
          else if ( propertyOwner[i].ownedHouses > 0 )
            charge += 25 * propertyOwner[i].ownedHouses;
        }
        this.printInfo("total of $" + charge);
	this.waitForPayment(charge, -3);
	break;
      case 15:	// xmas
        playerArray[curPlayer].money += 50;
	this.printMoney();
	break;
      default:
	this.printInfo("a chance card that does not exist was selected. (this is a bug) card number " + myNum);
    }
  }
  else if ( pile == "communitychest" )
  {
		//if we are out of cards then re-shuffle
    if ( this.communitychestShuffle.length <= 0 )
      this.communitychestShuffle = shuffleCards(communitychestCards.length);
		// take a card
    myNum = this.communitychestShuffle.pop();
    //myNum = 13;
		// print the card
    this.printInfo(communitychestCards[myNum]);

    switch ( myNum )
    {
      case 0:  // get out of jail free
        playerArray[curPlayer].jailcards++;
	break;
      case 1:	//'A collection has been taken up and everyone must donate 10% of his holdings to you (cash)',
        for (var i=0; i<prefs.numPlayers; i++) {
          if ( i == curPlayer ) continue;
          var donate = Math.round(playerArray[i].money * .1);
	  playerArray[curPlayer].money += donate;
          playerArray[i].money -= donate;
          this.printInfo(playerArray[i].playerName + " donates $" + donate);
	}
	this.printMoney();
	break;
      case 2:	// gold standard
        playerArray[curPlayer].money += 50;
	this.printMoney();
	break;
      case 3:	// Hospital
	this.waitForPayment(100, -3);
	break;
      case 4:	// services
        playerArray[curPlayer].money += 25;
	this.printMoney();
	break;
      case 5:	// doctor
	this.waitForPayment(50, -3);
	break;
      case 6:	// go to jail
        // wait until button
        this.goToJail();
        return "jail";
	break;
      case 7:	// bank error
        playerArray[curPlayer].money += 200;
	this.printMoney();
	break;
      case 8:	// insurance matures
        playerArray[curPlayer].money += 100;
	this.printMoney();
	break;
      case 9:	// stocks
        playerArray[curPlayer].money += 45;
	this.printMoney();
	break;
      case 10:	// tax refund
        playerArray[curPlayer].money += 20;
	this.printMoney();
	break;
      case 11:	// beauty contest
        playerArray[curPlayer].money += 11;
	this.printMoney();
	break;
      case 12:	// go
        // wait until button
        chanceExceptions = "fromcard";
	this.movePlayer(0);
        return "moved";
	break;
      case 13:	// nearest railroad
	chanceExceptions = "2xRR";
        var dest = -1;
	if ( playerArray[curPlayer].position <= 5 ) dest = 5;
	else if ( playerArray[curPlayer].position <= 15 ) dest = 15;
	else if ( playerArray[curPlayer].position <= 25 ) dest = 25;
	else if ( playerArray[curPlayer].position <= 35 ) dest = 35;
	else dest = 5;
	this.movePlayer(dest);
        return "moved";
	break;
      case 14:	// inherit
        playerArray[curPlayer].money += 100;
	this.printMoney();
	break;
      case 15:	// 'Grand Opera Opening<br>Collect $50 from every player for opening night seats'
        for (var i=0; i<playerList.length; i++) {
          if ( playerList[i] == curPlayer || playerArray[playerList[i]].bankrupt ) continue;
	  playerArray[curPlayer].money += 50;
          playerArray[playerList[i]].money -= 50;
	}
	this.printMoney();
	break;
      default:
	this.printInfo("a community chest card that does not exist was selected. (this is a bug) card number" + myNum);
    }
  }
}

BoardAssistant.prototype.inJail = function() {
try {
  //debugMessage("inJail");
  if ( playerArray[curPlayer].jailstate <= 0 ) return 0;

  //debugMessage("start in jail");
  this.printInfo( playerArray[curPlayer].playerName + ' is in Jail (turn ' + playerArray[curPlayer].jailturns + '). You may either attempt to roll doubles or else pay a $50 fine.' );

  this.setPurchaseButton('pay');
  this.setTurnButton('roll');

		// if we've been in jail for more than three times then you must pay
  if ( ! isComputer(curPlayer) ) {
    if ( playerArray[curPlayer].jailturns < 3 ) {
      var jailchoices = [];
      if ( playerArray[curPlayer].jailcards > 0 ) {
        jailchoices = [
            {label:$L("Card"), value:"pay"},
            {label:$L("Roll"), value:"roll"}
          ]
      }
      else {
        jailchoices = [
            {label:$L("Pay"), value:"pay"},
            {label:$L("Roll"), value:"roll"}
          ]
      }
      this.controller.showAlertDialog({
        onChoose: function(value) {
          if ( value == "pay" ) {
            if ( ! this.makeJailPayment() )
              this.printInfo(playerArray[curPlayer].playerName + " does not have $50");
          }
          else if ( value == "roll" ) {
            this.setPurchaseButton('clear');
            this.setTurnButton('none');
            this.rollDice();
          }
        },
        title: $L("Do you want to roll or pay $50?"),
        choices: jailchoices
      });
    }
    else {
      this.setTurnButton('jail');
    }
  }
  else {
		// if computer then buy out of jail
    if ( playerArray[curPlayer].jailturns >= 3 ) {
      if ( ! this.makeJailPayment() )
        if ( this.waitForPayment(50, -6) )
          this.rollDice();
    }
    else {
      //debugMessage("jail turns: " + playerArray[curPlayer].jailturns);
		// the more turns in jail the more likely to roll
      if ( ( Math.random() * 4 ) > playerArray[curPlayer].jailturns ) {
		// now try to pay $50
        //this.waitForPayment(50, -6);
        this.makeJailPayment();
		// but whether or not they pay roll
        this.rollDice();
      }
      else
        this.rollDice();
    }
  }
} catch(x) { debugMessage("Exception in in jail: " + x); }
}

BoardAssistant.prototype.goToJail = function() {
try {
  //debugMessage("start go to jail");
  playerArray[curPlayer].position = 10;
  this.printPlayer(curPlayer, 10);
  //this.printCard(10);

  playerArray[curPlayer].doubleRolls = 0;
  playerArray[curPlayer].jailstate++;
  //playerArray[curPlayer].jailturns++;

  /*
  if ( playerArray[curPlayer].jailstate <= 0 )
    this.printInfo(playerArray[curPlayer].playerName + " used a get out of Jail Free Card");
 		// wasn't in jail
  else if ( playerArray[curPlayer].jailstate == 1 ) {
    playerArray[curPlayer].jailturns = 0;
    this.printInfo(playerArray[curPlayer].playerName + " is in Jail");
  }
  */
  playerArray[curPlayer].jailturns = 0;
  this.printInfo(playerArray[curPlayer].playerName + " is in Jail");
  saveDynamicObjects();

  this.computerSettleDebts(curPlayer);
  saveDynamicObjects();

  if ( isComputer(curPlayer) && prefs.disableEndTurn == "true" )
    endTurnWrapper.delay(2, this);
  else
    this.setTurnButton('endturn');

} catch(x) { debugMessage("Exception in got to jail: " + x); }
}

BoardAssistant.prototype.waitForPayment = function(money, to) {
try {
  debugMessage("waitForPayment money: " + money + ", to: " + to);
  if ( isComputer(curPlayer) ) {
    if ( ! this.autoRaiseMoney(curPlayer, money) ) {
		// this is a bug because old stilloweto will get over-written
      debugMessage("couldn't raise");
      this.bankruptPlayer(curPlayer);
      //debugMessage("couldn't raise money");
      return 0;
    }
    else {
      playerArray[curPlayer].stillowe += money;
      playerArray[curPlayer].stilloweto = to;
      this.ballanceStillOwe(curPlayer);
      return 1;
    }
  }
  else {
    playerArray[curPlayer].stillowe += money;
    playerArray[curPlayer].stilloweto = to;
    if ( ! this.ballanceStillOwe(curPlayer) ) {
      this.setTurnButton('none');
      this.setPurchaseButton('pay');
      return 0;
    }
  }

  return 1;

} catch(x) { debugMessage("Exception in wait for payment: " + x); }
}

BoardAssistant.prototype.createPropertyDivs = function() {
  var txt = "";
  for ( var i=0; i<propertyArray.length; i++ )
    txt += '<div id="propdiv' + i + '" style="position:absolute;' + propertyArray[i][propertylocation] + '"></div>';
  this.controller.get('housingdiv').innerHTML = txt;

  this.updateHouses();
}

BoardAssistant.prototype.updateHouses = function() {
  for ( var i=0; i<propertyArray.length; i++ )
    this.printHouses(i);
}

BoardAssistant.prototype.printHouses = function(property) {
try {
  var grey = '#e0e0e8';
  var white = '#f4f4ff';
  if ( propertyOwner[property].owner != null ) {
    this.controller.get('propdiv' +  property).style.backgroundColor = grey;
    if ( propertyOwner[property].ownedHouses == 1 )
      this.controller.get('propdiv' +  property).innerHTML = '<div><img src="images/houses1.png"></div>';
    else if ( propertyOwner[property].ownedHouses == 2 )
      this.controller.get('propdiv' +  property).innerHTML = '<div><img src="images/houses2.png"></div>';
    else if ( propertyOwner[property].ownedHouses == 3 )
      this.controller.get('propdiv' +  property).innerHTML = '<div><img src="images/houses3.png"></div>';
    else if ( propertyOwner[property].ownedHouses == 4 )
      this.controller.get('propdiv' +  property).innerHTML = '<div><img src="images/houses4.png"></div>';
    else if ( propertyOwner[property].ownedHouses >= 5 )
      this.controller.get('propdiv' +  property).innerHTML = '<div><img src="images/houses5.png"></div>';
  }
  else {
    this.controller.get('propdiv' +  property).style.backgroundColor = white;
    this.controller.get('propdiv' +  property).innerHTML = '';
  }
} catch(x) { debugMessage("Exception in printHouses: " + x); }
}

debugStuff = function() {
  if ( ! debug ) return 0;

                // some debug options for testing...
  propertyOwner[1].owner = 0;
  propertyOwner[1].ownedHouses = 5;
  propertyOwner[3].owner = 0;
  propertyOwner[3].ownedHouses = 5;
  propertyOwner[6].owner = 0;
  propertyOwner[6].ownedHouses = 5;
  propertyOwner[8].owner = 0;
  propertyOwner[8].ownedHouses = 5;
  propertyOwner[9].owner = 0;
  propertyOwner[9].ownedHouses = 5;
  //propertyOwner[11].owner = playerList[2];
  //propertyOwner[13].owner = playerList[2];
  //propertyOwner[14].owner = playerList[2];

  //propertyOwner[5].owner = 0;
  //propertyOwner[15].owner = 0;
  //propertyOwner[25].owner = 0;
  //propertyOwner[35].owner = 0;
  //propertyOwner[39].owner = 1;

  playerArray[ playerList[0] ].money = 49;
  playerArray[ playerList[1] ].money = 49;
  playerArray[ playerList[2] ].money = 49;
  playerArray[0].money = 15000;
  //playerArray[0].position = 38;
  //playerArray[1].position = 38;
  //playerArray[2].position = 38;
  //playerArray[0].jailstate = 1;
  //playerArray[0].jailcards = 1;
  //playerArray[ playerList[1] ].jailstate = 1;
  //playerArray[ playerList[1] ].jailcards = 1;
}

BoardAssistant.prototype.activate = function(event) {
	/* put in event handlers here that should only be in effect when this scene is active. For
	   example, key handlers that are observing the document */
  this.printMoney();
  this.updateTics();
  this.updateHouses();

  saveDynamicObjects();
  if ( this.pause ) {
    this.pause = false;
    if ( isComputer(curPlayer) )
      playturn.delay(1, this);
  }

  if ( killGame )
    killGame = false;
}

BoardAssistant.prototype.deactivate = function(event) {
	this.pause = true;
	Mojo.Event.stopListening(this.controller.get('PropertiesButtonID'),Mojo.Event.tap, this.openPropsStage.bind(this));
	Mojo.Event.stopListening(this.controller.get('PurchaseID'),Mojo.Event.tap, this.makePayment.bind(this));
	Mojo.Event.stopListening(this.controller.get('TurnButtonID'),Mojo.Event.tap, this.turnButtonAction.bind(this));
        Mojo.Event.stopListening(this.controller.get('ClosePropertyID'), Mojo.Event.tap, this.closeProperty.bind(this));
	this.controller.stopListening(document, 'shaking', this.turnButtonAction.bindAsEventListener(this));
}

BoardAssistant.prototype.cleanup = function(event) {
	this.pause = true;
	Mojo.Event.stopListening(this.controller.get('PropertiesButtonID'),Mojo.Event.tap, this.openPropsStage.bind(this));
	Mojo.Event.stopListening(this.controller.get('TurnButtonID'),Mojo.Event.tap, this.turnButtonAction.bind(this));
	Mojo.Event.stopListening(this.controller.get('PurchaseID'),Mojo.Event.tap, this.makePayment.bind(this));
        Mojo.Event.stopListening(this.controller.get('ClosePropertyID'), Mojo.Event.tap, this.closeProperty.bind(this));
	this.controller.stopListening(document, 'shaking', this.turnButtonAction.bindAsEventListener(this));
}
